diagnostics_channel: add opt-in subscriber suppression via bypassBy and bypassed() - #63651
diagnostics_channel: add opt-in subscriber suppression via bypassBy and bypassed()#63651DivyanshuX9 wants to merge 43 commits into
Conversation
Defer non-critical warnings to the next event loop iteration when can_call_into_js() returns false. This prevents crashes when V8 emits warnings during REPL preview evaluation or other contexts where JavaScript execution is temporarily forbidden. When a warning is emitted inside DisallowJavascriptExecutionScope, ProcessEmitWarningGeneric cannot be called immediately. Instead, use env->SetImmediate() to queue the warning emission for after the scope exits. This preserves full warning formatting, deprecation codes, and --redirect-warnings routing. Signed-off-by: Divyanshu Sharma <Divyanshu88999@gmail.com>
Refs: nodejs#63623 Refs: nodejs#63651 Signed-off-by: Divyanshu Sharma <divyanshu88999@gmail.com>
5b4110a to
8b122c2
Compare
Refs: nodejs#63623 Refs: nodejs#63651 Signed-off-by: Divyanshu Sharma <divyanshu88999@gmail.com>
Refs: nodejs#63623 Refs: nodejs#63651 Signed-off-by: Divyanshu Sharma <divyanshu88999@gmail.com>
8b122c2 to
e4aea85
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #63651 +/- ##
==========================================
- Coverage 90.16% 90.13% -0.03%
==========================================
Files 744 744
Lines 242518 242667 +149
Branches 45692 45723 +31
==========================================
+ Hits 218663 218729 +66
- Misses 15349 15443 +94
+ Partials 8506 8495 -11
🚀 New features to boost your workflow:
|
Qard
left a comment
There was a problem hiding this comment.
Tests are missing a lot of necessary common.mustCall(fn) wrappers.
Also, it seems like this was just vibe-coded without reviewing the output before submitting the PR. Please ensure it is in a good state and that the test suite and lint passes before submitting.
Signed-off-by: Divyanshu Sharma <divyanshu88999@gmail.com>
Signed-off-by: Divyanshu Sharma <divyanshu88999@gmail.com>
Signed-off-by: Divyanshu Sharma <divyanshu88999@gmail.com>
Signed-off-by: Divyanshu Sharma <divyanshu88999@gmail.com>
…update tests to use common.mustCall
|
@Qard , thanks for the detailed review. So far the checklist of what i have fixed in the latest push: [] Removed the impossible ALS try/catch fallback Ready for re-review and any changes if you want, when you have time please review it. |
0f6e780 to
8fa6fd8
Compare
Signed-off-by: Divyanshu Sharma <divyanshu88999@gmail.com>
8fa6fd8 to
b8194af
Compare
|
The node_errors.cc change still seems to be present. |
…ove SetImmediate deferral) Signed-off-by: Divyanshu Sharma <divyanshu88999@gmail.com>
Signed-off-by: Divyanshu Sharma <divyanshu88999@gmail.com>
|
I think implementation + tests + docs of a new public API should come in one PR. |
|
@Flarna Well once BridgeAR also mentioned about doc
at that time was not sure how far reviews will go ,also @rochdev wanted some examples rightaway, So made a seperate PR for that to keep this one clean , yes if i get a green signal to land this one will will update and merge that pr doc in this one. |
Signed-off-by: Divyanshu Sharma <divyanshu88999@gmail.com>
|
@Flarna i have moved all the docs here |
Signed-off-by: Divyanshu Sharma <divyanshu88999@gmail.com>
2ba3a7a to
f7f593e
Compare
|
@Flarna , lowkey I have addressed all feedback in latest push:
Thank you for the thorough review. |
also @Flarna at 251 line is this correct or should i just remove REPLACE ME with the stability:1.1 right away |
|
No, the The stability index is just documentation and independent of that. |
Signed-off-by: Divyanshu Sharma <divyanshu88999@gmail.com>
2fccc37 to
58785bb
Compare
|
@BridgeAR following up on your performance concern, ran a microbenchmark on the normal-subscriber hot path (1,000,000 iterations, no bypass() active):
Test 1 is the pure normal path with no bypass subscriber registered at all, the overhead is just the _bypassSubscribers !== null null-check plus the extra fields on the channel object, comes out to around 2.2ns per call.
|
Signed-off-by: DivyanshuX9 <divyanshu88999@gmail.com>
81685dd to
aa285c8
Compare
Signed-off-by: Divyanshu Sharma <divyanshu88999@gmail.com>
Three bad-merge fragments were committed without conflict markers: - unsubscribe: spurious decRef/maybeMarkInactive before return false - bindStore: stale bindStore(store, transform) fragment injected inside the else block of bindStore(store, transform, options), with missing closing braces for the else block and the method - unbindStore: spurious delete/decRef/maybeMarkInactive before return false All three were remnants of the pre-bypass single-path implementation that were not removed during the bypass-feature merge. Signed-off-by: Divyanshu Sharma <divyanshu88999@gmail.com>
…s entries Signed-off-by: Divyanshu Sharma <divyanshu88999@gmail.com>
The subscriber buffer (dc_binding.subscribers) is replaced with a new
larger TypedArray when native channel storage grows past its initial
capacity. The old code destructured it once at module load:
const { subscribers: subscriberCounts } = dc_binding;
After growth, dc_binding.subscribers points to the new array but
subscriberCounts still holds a reference to the old one. Any
subscribe/unsubscribe/bindStore/unbindStore call after growth would
increment/decrement the stale array, leaving the live array at zero.
Channel::HasSubscribers() reads from the live array and would return
false even with active subscribers, breaking the C++ test
NativeChannelsGrowSubscriberStorage.
Fix: remove the cached destructuring and access dc_binding.subscribers
directly at every call site. The comment above the binding already
stated this requirement; the code just did not follow it.
Signed-off-by: Divyanshu Sharma <divyanshu88999@gmail.com>
ActiveChannel.publish() accessed this._subscribers with optional chaining (subscribers?.length || 0). This is unnecessary because: - _subscribers is always initialized to [] by markActive() before any ActiveChannel method can be called - maybeMarkInactive() sets _subscribers back to undefined only after switching the prototype back to Channel.prototype, so ActiveChannel methods are never reachable with a nullish _subscribers Use subscribers.length directly. Signed-off-by: Divyanshu Sharma <divyanshu88999@gmail.com>


Summary
Adds opt-in subscriber suppression to
diagnostics_channelso APMagents can prevent recursive instrumentation when their own internal
code calls into instrumented libraries.
What Changed
lib/diagnostics_channel.jssuppressed(key, fn, thisArg, ...args)- runsfnwiththe given key active in the current async context
subscribe()andbindStore()accept{ subscriberId }optionpath has zero overhead, ALS is only hit when bypass subscribers exist
AsyncLocalStorageinitialization viagetSuppressionsStorage()async_hooks is available
validateBypassKey()helper for all key validationtest/parallel/test-diagnostics-channel-suppression.jsstore, nested, and type validation cases
Why
APM agents currently implement suppression themselves using a
custom ALS noop marker - every vendor reimplements the same
pattern differently. Moving it into core:
Backward Compatibility
Naming
As per @bengl final name is "Bypass"
Addresses:#63623